package ability

import (
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"sjy/customcmd/src/constants"
	"sjy/customcmd/src/entity"
	"sjy/customcmd/src/event"
	"sjy/customcmd/src/utils"
	"strings"

	"github.com/ahmetb/go-linq/v3"
	"github.com/astaxie/beego/logs"
)

var (
	Ps1DefaultConfig = &entity.PS1Config{
		ScriptName:  "exec",
		ShowHelpUrl: true,
		Args:        []string{},
	}
	PowerShellInstance = FuncManager.Register(
		&PowerShellClass{
			FuncObjBase: &FuncObjBase{
				ClassName: constants.PowerShell.Code,
			},
		},
	)
)

type PowerShellClass struct {
	*FuncObjBase
}

func (r *PowerShellClass) Execute(obj *FuncEntity) {
	PowerShellExcute(obj)
}

func PowerShellExcute(obj *FuncEntity) {
	var cmd *exec.Cmd
	// 获取ps1配置
	config := getPs1Config()

	// 显示帮助url
	showPs1Help(config)

	exec.Command("chcp", "65001").Run()

	scriptpath, ok := getWdScript(config)
	if !ok {
		utils.Info("当前工作目录下没有找到：%s", scriptpath)
		return
	}
	// -ExecutionPolicy Bypass 可以绕过 PowerShell 的执行策略限制
	args := []string{"-ExecutionPolicy", "Bypass", "-File", scriptpath}
	args = append(args, getPs1Args(config, obj.Paramenter)...)
	// 兼容pwsh
	if runtime.GOOS == "windows" {
		utils.Info("执行命令：%s", "powershell "+strings.Join(args, " "))
		cmd = exec.Command("powershell", args...)
	} else {
		utils.Info("执行命令：%s", "pwsh "+strings.Join(args, " "))
		cmd = exec.Command("pwsh", args...)
	}

	// 获取命令输出
	output, err := cmd.CombinedOutput()
	if err != nil {
		// 处理错误
		logs.Error("Error executing PowerShell script:", scriptpath, err)
		return
	}
	utils.Info("%s", string(output))
}

func showPs1Help(config *entity.PS1Config) {
	if !config.ShowHelpUrl {
		return
	}

	utils.Info("%s", constants.Infomation.GiteeMaster)
	utils.Info("Ps1 功能帮助：%s", constants.Infomation.Ps1Help)
}

func getPs1Config() *entity.PS1Config {
	result := event.GetConfig(func(obj *entity.MainConfig) entity.FieldInterface {
		return obj.Ps1
	})
	config, ok := result.(*entity.PS1Config)
	if ok && config != nil && !config.AllEmpty() {
		return config
	} else {
		return Ps1DefaultConfig
	}
}

func getPs1Args(config *entity.PS1Config, param *entity.Param) []string {
	var args []string
	linq.From(param.CmdArgs).WhereT(func(str string) bool {
		return str != ""
	}).ToSlice(&args)

	if len(args) > 0 {
		return args
	}

	linq.From(config.Args).WhereT(func(str string) bool {
		return str != ""
	}).ToSlice(&args)

	return args
}

func getWdScript(config *entity.PS1Config) (string, bool) {
	// 目标Powershell脚本路径
	scriptpath := filepath.Join(scriptRoot(), config.ScriptName+".ps1")
	if checkFile(scriptpath) {
		return scriptpath, true
	}
	return scriptpath, false
}

func scriptRoot() string {
	// 获取当前工作目录
	currentDir, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	// production 环境
	if utils.IsPackage() {
		return currentDir
	}
	// 开发环境
	return constants.AppRoot
}

func checkFile(path string) bool {
	_, err := os.Stat(path)
	// 文件存在
	if err == nil {
		return true
	}

	// 文件不存在
	if os.IsNotExist(err) {
		return false
	}

	panic(err)
}
